package xyz.zdsoft.common.utils;

public class RegexUtils {

    //密码至少包含：数字和英文字母，长度6-20
    public static final String PASSWORD1 = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$";

    //密码至少包含：数字,英文,字符中的两种以上，长度6-16
    public static final String PASSWORD2 = "^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)])+$).{6,16}$";

    //密码至少包含数字跟字母，可以有字符，长度6-20
    public static final String PASSWORD3 = "(?=.*([a-zA-Z].*))(?=.*[0-9].*)[a-zA-Z0-9-*/+.~!@#$%^&*()]{6,20}$";

    //身份证正则表达式
    public static final String IDNUMBER = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
            "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";

    //匹配国内各大运营商手机号段（最常用）
    public static final String PHONE = "^((13[0-9])|(14[5-9])|(15([0-3]|[5-9]))|(16[0-9])|(17[0-8])|(18[0-9])|(19[1|3])|(19[5|6])|(19[8|9]))\\d{8}$";

    //匹配国内座机 如 xxx(区号)-00000000(本地号)
    public static final String PHONE1 = "0\\d{2}\\d{8}|0\\d{3}-\\d{7}";
    public static final String PHONE2 = "0\\d{2}-\\d{8}|0\\d{3}-\\d{7}";
    //匹配国内以95开头的5位银行号段
    public static final String PHONE3 = "^95.{3}$";
    //匹配以00、+、400、950开头的所有电话(疑似诈骗电话)
    public static final String PHONE4 = "^00.*";
    public static final String PHONE5 = "^\\+.*";
    public static final String PHONE6 = "^400.*";
    public static final String PHONE7 = "^950.*";

    /**
     * 大陆地区固话及小灵通
     * 区号：010,020,021,022,023,024,025,027,028,029
     * 号码：七位或八位
     */
    public static final String PHONE8 = "^0(10|2[0-5789]|\\d{3})\\d{7,8}$";

    /**
     * 手机号码
     * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     * 联通：130,131,132,152,155,156,185,186
     * 电信：133,1349,153,180,189
     */
    public static final String PHONE9 = "^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";


    /**
     * 中国移动：china mobile
     * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     */
    public static final String PHONE10 = "^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";


    /**
     * 中国联通：china unicom
     * 130,131,132,152,155,156,185,186
     */
    public static final String PHONE11 = "^1(3[0-2]|5[256]|8[56])\\d{8}$";


    /**
     * 中国电信：china telecom
     * 133,1349,153,180,189
     */
    public static final String PHONE12 = "^1((33|53|8[09])[0-9]|349)\\d{7}$";


    public static final String EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";


    /**
     * 验证字符串是否是身份证号码
     * @param idNumber
     * @return
     */
    public static boolean isIdNumber(String idNumber) {
        if (idNumber == null || "".equals(idNumber)) {
            return false;
        }
        // 定义判别用户身份证号的正则表达式（15位或者18位，最后一位可以为字母）
//        String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
//                "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
        //假设18位身份证号码:41000119910101123X  410001 19910101 123X
        //^开头
        //[1-9] 第一位1-9中的一个      4
        //\\d{5} 五位数字           10001（前六位省市县地区）
        //(18|19|20)                19（现阶段可能取值范围18xx-20xx年）
        //\\d{2}                    91（年份）
        //((0[1-9])|(10|11|12))     01（月份）
        //(([0-2][1-9])|10|20|30|31)01（日期）
        //\\d{3} 三位数字            123（第十七位奇数代表男，偶数代表女）
        //[0-9Xx] 0123456789Xx其中的一个 X（第十八位为校验值）
        //$结尾

        //假设15位身份证号码:410001910101123  410001 910101 123
        //^开头
        //[1-9] 第一位1-9中的一个      4
        //\\d{5} 五位数字           10001（前六位省市县地区）
        //\\d{2}                    91（年份）
        //((0[1-9])|(10|11|12))     01（月份）
        //(([0-2][1-9])|10|20|30|31)01（日期）
        //\\d{3} 三位数字            123（第十五位奇数代表男，偶数代表女），15位身份证不含X
        //$结尾
        boolean matches = idNumber.matches(IDNUMBER);
        //判断第18位校验值
        if (matches) {
            if (idNumber.length() == 18) {
                try {
                    char[] charArray = idNumber.toCharArray();
                    //前十七位加权因子
                    int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
                    //这是除以11后，可能产生的11位余数对应的验证码
                    String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
                    int sum = 0;
                    for (int i = 0; i < idCardWi.length; i++) {
                        int current = Integer.parseInt(String.valueOf(charArray[i]));
                        int count = current * idCardWi[i];
                        sum += count;
                    }
                    char idCardLast = charArray[17];
                    int idCardMod = sum % 11;
                    return idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase());

                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

        }
        return matches;
    }

    /**
     * 验证字符串是否是手机号码
     * @param phoneNumber
     * @return
     */
    public static boolean isPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || "".equals(phoneNumber)) {
            return false;
        }
        return phoneNumber.matches(PHONE);
    }

    /**
     * 验证字符串是否是邮箱
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {
        if (email == null || "".equals(email)) {
            return false;
        }
        return email.matches(EMAIL);
    }
}
